home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / net3d-0.08 / client.c < prev    next >
C/C++ Source or Header  |  1995-06-22  |  12KB  |  453 lines

  1. /* client.c
  2.  *
  3.  * code to connect to the server and call other functions to run
  4.  * the game
  5.  */
  6. #include "net3d.h"
  7.  
  8. static void displayhelp(char *);
  9.  
  10. bool singlep=false;            /* is this a net-game? */
  11. char *pnames[MAX_PLAYERS];        /* names of all players */
  12. int sock;                /* connection to server */
  13.  
  14. int main(int argc, char **argv)
  15. {
  16. char name[100]="";            /* this player's name */
  17. struct object *ohead=NULL;        /* in-game object list */
  18. struct vehicle *vhead=NULL;        /* in-game vehicle list */
  19. struct map mp;                /* game world terrain details */
  20. int number;                /* client's player number */
  21. struct vehicle *drive;            /* vehicle client is driving */
  22. bool alive;                /* is this player still alive */
  23. double ltime;                /* time at last check of fps */
  24. #if DISPLAYFPS
  25. int frm=0;                /* frames drawn */
  26. #endif
  27. struct view vw;                /* player's 3d viewpoint */
  28. int vmode=4;                /* view of player's vehicle */
  29. struct vehicle *pvehicles[MAX_PLAYERS];    /* vehicles players drive */
  30. int plcount;                /* number of people playing */
  31. double servertime=0.0;            /* game time from server */
  32. bool winner=false;            /* has someone won? */
  33. FILE *dotfp;                /* fp for .surrealrc file */
  34. char dotsurpath[80];            /* file path to .surrealrc */
  35. int drvid;                /* vid of current vehicle */
  36. struct point zpoint={0,0,0};        /* constant 0,0,0 point */
  37. int finalcountdown = 100;        /* after death, the number of frames
  38.                      * until exit */
  39. char currentdir[100];            /* path to .v file in current dir */
  40. char net3ddir[100];            /* path to .v file in NET3D_DIR */
  41.  
  42. int i;                    /* scratch */
  43. struct vehicle *vpos;
  44. FILE *tfp;
  45.  
  46. /* initialize the default map.
  47.  */
  48. mp.ht = mp.gr = NULL;                /* No hills by default */
  49. mp.map_w = mp.map_h = 0;
  50. mp.size = mp.scale = 0.0;
  51. mp.lookout.x = 0; mp.lookout.y = 0; mp.lookout.z = 0;
  52. mp.rfade = 0; mp.gfade = 0; mp.bfade = 0;    /* fade to black */
  53. mp.tcol = mp.gcol = 2;                /* green hills & ground */
  54. mp.skycol = 32;                    /* black sky */
  55. mp.ground = True;                /* ground does exist */
  56. mp.stars = NULL; mp.scount = 0;            /* no stars */
  57.  
  58. /* Display user help.
  59.  */
  60. if (argc == 1) {
  61.     printf("usage : Single player : %s <vehicle files>\n",argv[0]);
  62.     printf("        Network game  : %s <server> <player name>\n",argv[0]);
  63.     printf("        Help          : %s -help\n",argv[0]);
  64.     exit(0);
  65.     }
  66. if (!strcmp(argv[1],"-help")) {
  67.     displayhelp(argv[0]);
  68.     exit(0);
  69.     }
  70.  
  71. /* setup sin and cos caches */
  72. initcaches();
  73.  
  74. /* We want children automatically reaped by default */
  75. signal(SIGCHLD,SIG_IGN);
  76.  
  77. /* read key configuration file.
  78.  */
  79. sprintf(dotsurpath,"%s/%s",getenv("HOME"),KEYFILE);
  80. if ((dotfp = fopen(dotsurpath,"r"))) {
  81.     readkeyfile(dotfp);
  82.     fclose(dotfp);
  83.     }
  84.  
  85. readextravehicles();
  86.  
  87. /* Look for a file named by the first command line argument, in the current
  88.  * directory and NET3D_DIR. If it exists, then this is a single player game.
  89.  * If not, then the first command line argument is the name of the server,
  90.  * and this is a multi-player game.
  91.  */
  92. sprintf(currentdir,"%s",argv[1]);
  93. sprintf(net3ddir,"%s/%s",NET3D_DIR,argv[1]);
  94. if ((tfp = fopen(currentdir,"r")) || (tfp = fopen(net3ddir,"r"))) {
  95.     /* using single player mode.
  96.      */
  97.     fclose(tfp);
  98.     singlep=true;
  99.     /* read map and vehicle files.
  100.      */
  101.     for(i=1; i<argc; i++) {
  102.         int pifd;
  103.         struct stat dummy;
  104.         
  105.         /* look for the vehicle file in the current directory, or
  106.          * if not found, in the directory defined by NET3D_DIR.
  107.          */
  108.         sprintf(currentdir,"%s",argv[i]);
  109.         sprintf(net3ddir,"%s/%s",NET3D_DIR,argv[i]);
  110.         if (stat(currentdir,&dummy) != -1) {
  111.             pifd=pipethrough(CPPPATH,currentdir);
  112.             readfile(&ohead,&vhead,pifd,&mp);
  113.             close(pifd);
  114.             printf("done reading %s\n",currentdir);
  115.             }
  116.         else if (stat(net3ddir,&dummy) != -1) {
  117.             pifd=pipethrough(CPPPATH,net3ddir);
  118.             readfile(&ohead,&vhead,pifd,&mp);
  119.             close(pifd);
  120.             printf("done reading %s\n",net3ddir);
  121.             }
  122.         else {
  123.             printf("file %s not found!\n",argv[i]);
  124.             exit(0);
  125.             }
  126.         }
  127.  
  128.     /* check for lack of vehicles */
  129.     if (vhead == NULL) {
  130.         printf("No vehicles found!\n");
  131.         exit(1);
  132.         }
  133.  
  134.     /* set up the things usually got from the server */
  135.     plcount=1;
  136.     pnames[0]="Solo";
  137.     makemap(&ohead,&mp);
  138.     number=0;
  139.     pvehicles[0]=vhead;
  140.  
  141.     /* put the initial game time into the pipe */
  142.     sprintf(fakepipe,"%f\n",gametime());
  143.     }
  144. else {
  145.     char *ver;
  146.  
  147.     /* multi-player mode */
  148.     sock=OpenSend(argv[1]);
  149.     printf("Connected to server\n");
  150.  
  151.     /* check version */
  152.     ver = ngets(sock);
  153.     if (strcmp(ver,NET3D_VERSION)) {
  154.         nprintf(sock,"%s\n",VERSION_ERROR);
  155.         close(sock);
  156.         printf("Rejected by server! This client is version %s,"
  157.                " but the server is version %s\n",NET3D_VERSION,
  158.                ver);
  159.         exit(1);
  160.         }
  161.  
  162.     if (argc > 2) {
  163.         /* if a name is given, use it */
  164.         int i;
  165.  
  166.         for(i=2; i<argc; i++) {
  167.             strcat(name,argv[i]);
  168.             strcat(name," ");
  169.             }
  170.         }
  171.     else {
  172.         /* Try to get the user's name from $LOGNAME, $USER or
  173.          * cuserid().
  174.          */
  175.         char *env_logname, *env_user;
  176.  
  177.         env_logname = getenv("LOGNAME");
  178.         env_user = getenv("USER");
  179.         if (env_logname)
  180.             strcpy(name,env_logname);
  181.         else if (env_user)
  182.             strcpy(name,env_user);
  183.         else
  184.             cuserid(name);
  185.         }
  186.     /* send player's name to the server */
  187.     nprintf(sock,"%s\n",name);
  188.  
  189.     /* read the pre-processed vehicle files from the server, for reading
  190.      * into the object and vehicle lists.
  191.      */
  192.     readfile(&ohead,&vhead,sock,&mp);
  193.     printf("done reading vehicles\n");
  194.  
  195.     /* create the map polygons from the map array */
  196.     makemap(&ohead,&mp);
  197.  
  198.     /* find player number, and from it the vehicle to drive */
  199.     number=atoi(ngets(sock));
  200.     if (number==-1) {
  201.         printf("no vehicles available :(\n");
  202.         shutdown(sock,2);
  203.         close(sock);
  204.         exit(2);
  205.         }
  206.  
  207.     /* read true number of players from server, and from this determine
  208.      * which player controls which vehicle
  209.      */
  210.     plcount=atoi(ngets(sock));
  211.     vpos=vhead;
  212.     for(i=0; i<plcount; i++) {
  213.         pvehicles[i] = vpos;
  214.         vpos->owner  = o_network;
  215.         vpos->pnum   = i;
  216.         vpos = vpos->next;
  217.         }
  218.  
  219.     /* read names of all players from the server */
  220.     for(i=0; i<plcount; i++) {
  221.         pnames[i]=strdupe(ngets(sock));
  222.         printf("player %d is %s\n",i,pnames[i]);
  223.         }
  224.     }
  225.  
  226. /* display some useful info to the player */
  227. worldinfo(vhead,ohead);
  228. printcontrols();
  229.  
  230. drive=pvehicles[number];
  231. drive->pnum = number;
  232. printf("You are player %d, driving vehicle %s\n",number,drive->code);
  233.  
  234. /* setup 3-d world */
  235. drive->owner=o_player;
  236. drvid = drive->vid;
  237. alive=true;
  238. initX(&mp, argc, argv);
  239. initmightsaves(ohead);
  240. initmightsaves(eohead);
  241. readicons();
  242. playertype = findbycode(evhead,"player")->type;
  243.  
  244. /* set up initial viewing parameters */
  245. vw.d=EYE_DISTANCE;
  246. createcamera(drive,&vw,vmode,&mp,vhead);
  247. vw.last.n = vw.last.u = vw.last.v = zpoint;
  248. vw.last.vrp = vw.vrp;
  249. vw.last.vmode = 0;
  250. init3d(&mp,&vw);
  251. ltime=gametime();
  252. calcbboxes(vhead);
  253.  
  254. /* register functions to be called on break */
  255. if (!singlep) {
  256.     signal(SIGINT,termhandler);
  257.     signal(SIGTERM,termhandler);
  258.     XSetIOErrorHandler(xerrorhandler);
  259.     }
  260.  
  261. /* play the game */
  262. while(1) {
  263.     if (alive) {
  264.         /* only re-calculate the view if the player still
  265.          * lives. once dead, the viewpoint lingers at the
  266.          * place of death indefinately :)
  267.          */
  268.         createcamera(drive,&vw,vmode,&mp,vhead);
  269.         }
  270.  
  271.     /* seed the random number generator with a time from
  272.      * the server, to make sure all clients are in sync.
  273.      */
  274.     srand(((int)servertime)*1000);
  275.  
  276.     /* draw the 3-d world, and move vehicles in it appropriately, 
  277.      * but only on the second time around the loop, after a time
  278.      * has been read from the server
  279.      */
  280.     if (servertime) {
  281.         cyclefire(servertime);
  282.         worldtoview(&vw,ohead,drive,vmode);
  283.         ohead=depthsort(ohead,&vw);
  284.         render(&vw,ohead,drive,vmode,&mp);
  285.  
  286.         /* Only draw the radar and info if the player is in the
  287.          * cockpit of a vehicle */
  288.         if (vmode==4 || vmode==6) {
  289.             drawradar(vhead,drive);
  290.             drawinfo(drive);
  291.             }
  292.         if (alive && drive) {
  293.             drawvmode(vmode,drive);
  294.             drawbuildicons();
  295.             }
  296.         drawextras(drive,winner);
  297.         controlvehicles(&vhead,&ohead);
  298.         movevehicles(&vhead,&ohead,&mp,servertime);
  299.         growtrees(&vhead,&ohead);
  300.         }
  301.  
  302.     if (alive && !drive->alive) {
  303.         /* either the player is dead, or they have transfered
  304.          * to another vehicle.
  305.          */
  306.         if (drive->transfer != -1) {
  307.             /* they have transferred */
  308.             struct vehicle *v;
  309.  
  310.             /* v = vehicle transferred to */
  311.             v = findbyvid(vhead,drive->transfer);
  312.             if (!v) {
  313.                 printf("vid for transfer not found!\n");
  314.                 exit(20);
  315.                 }
  316.             /* free the old vehicle, and change the drive 
  317.              * pointer and drvid to indicate that a new vehicle
  318.              * is now being driven.
  319.              */
  320.             v->owner = drive->owner;
  321.             free(drive);
  322.             drive = v;
  323.             drvid = drive->vid;
  324.             }
  325.         else {
  326.             /* player has just died. Tell the server, and
  327.              * clean up their vehicle */
  328.             alive=false;
  329.             printf("dead\n");
  330.             free(drive);
  331.             drive=NULL;
  332.             if (!singlep) {
  333.                 /* tell server this client is dead */
  334.                 nprintf(sock,"d");
  335.                 }
  336.             }
  337.         }
  338.  
  339. #if DISPLAYFPS
  340.     /* calculate frames/second */
  341.     frm++;
  342.     if (frm==100 && servertime) {
  343.         double ntime;            /* current time */
  344.  
  345.         ntime=servertime;
  346.         printf("%lf fps\n",100.0/(ntime-ltime));
  347.         ltime=ntime;
  348.         frm=0;
  349.         }
  350. #endif
  351.  
  352. #if DISPLAYCACHEINFO
  353.     /* display efficiency of map caching */
  354.     if (frm == 0) {
  355.         double hitpercent;
  356.  
  357.         if (mappointsdone) {
  358.             hitpercent = (mapcachehits/(double)mappointsdone) * 100;
  359.             printf("map cache %.2lf ",hitpercent);
  360.             mapcachehits = mappointsdone = 0.0;
  361.             }
  362.  
  363.         if (sincalls) {
  364.             hitpercent = (sincachehits / (double)sincalls) * 100;
  365.             printf("sin cache %.2lf",hitpercent);
  366.             sincachehits = sincalls = 0.0;
  367.             }
  368.  
  369.         printf("\n");
  370.         }
  371. #endif
  372.  
  373.     /* Read commands and the new game time from the server */
  374.     if (singlep)
  375.         servertime=readnet(&vhead,&ohead,&winner,&drvid);
  376.     else
  377.         servertime=readnet(&vhead,&ohead,&winner,&drvid);
  378.  
  379.     /* check for a change in the player's vehicle, after they
  380.      * have ejected.
  381.      */
  382.     if (drive && drvid != drive->vid) {
  383.         /* a new vehicle! search the list for the vehicle
  384.          * structure matching the new vid.
  385.          */
  386.         drive = findbyvid(vhead,drvid);
  387.         if (!drive) {
  388.             printf(    "The vid for the ejected player doesn't\n"
  389.                 "match any in the list!!!\n");
  390.             exit(20);
  391.             }
  392.         }
  393.  
  394.     /* If the player is still alive, call readkeys() as normal,
  395.      * otherwise pass in a NULL to indicate that the player is
  396.      * dead.
  397.      */
  398.     if (alive) {
  399.         if (singlep)
  400.             readkeys(&vmode,drive,vhead,servertime);
  401.         else
  402.             readkeys(&vmode,drive,vhead,servertime);
  403.         }
  404.     else {
  405.         if (singlep)
  406.             readkeys(&vmode,NULL,vhead,servertime);
  407.         else
  408.             readkeys(&vmode,NULL,vhead,servertime);
  409.         }
  410.  
  411.     /* After death, start the final countdown and exit when it REAches 0.
  412.      */
  413.     if (!alive && singlep)
  414.         if (!(finalcountdown--))
  415.             exit(0);
  416.     }
  417.  
  418. /* close connection to the server */
  419. if (!singlep) {
  420.     shutdown(sock,2);
  421.     close(sock);
  422.     }
  423. return(0);
  424. }
  425.  
  426. static void displayhelp(char *cn)
  427. {
  428. printf(
  429. "net3d client help\n"
  430. "-----------------\n"
  431. "Single player mode : To start net3d in single-player mode, type :\n"
  432. "                     %s <vehicle file> <vehicle file> ... \n"
  433. "                     Vehicle files have the extension .v, and at least\n"
  434. "                     one must be given. If multiple vehicle files are\n"
  435. "                     listed, then the last vehicle in the last file will\n"
  436. "                     be the one driven in the game.\n"
  437. "\n"
  438. "                     For example, if you typed  %s map.v tank.v\n"
  439. "                     then you would be controlling a tank, among scenery\n"
  440. "                     and other vehicles from map.v\n"
  441. "\n"
  442. "\n"
  443. "Multiplayer mode   : To start net3d in multi-player (networked) mode, type :\n"
  444. "                     %s <server> <name>\n"
  445. "                     <server> is the machine on which the net3d server is\n"
  446. "                     running, and <name> is the name identifying you in\n"
  447. "                     the game. The vehicle you control in the game is\n"
  448. "                     determined by the server, which assigns a vehicle to\n"
  449. "                     each player.\n"
  450. ,cn,cn,cn);
  451. }
  452.  
  453.